package org.czp.sockect;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.czp.message.MessageListener;
import org.czp.message.MessageQuue;
import org.czp.message.PrintMessgeListener;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;

public class Transport extends WebSocketServlet {

	private static final long serialVersionUID = -7289719281366784056L;
	private ExecutorService executor;
	Set<TextWebSocket> members;
	MessageListener listener;

	public Transport() {
		members = new CopyOnWriteArraySet<TextWebSocket>();
		executor = Executors.newFixedThreadPool(2);
		listener = new PrintMessgeListener();
	}

	@Override
	public void destroy() {
		executor.shutdownNow();
		super.destroy();
	}

	public void init() throws ServletException {
		super.init();
		parseLitener();
		executor.execute(new Runnable() {

			@Override
			public void run() {
				MessageQuue msg = MessageQuue.getInstance();
				while (!Thread.interrupted()) {
					try {
						String obj = msg.getTextMessage();
						for (TextWebSocket member : members) {
							if (!member.isOpen())
								continue;
							try {
								member.sendMessage(obj);
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		executor.execute(new Runnable() {

			@Override
			public void run() {
				MessageQuue msg = MessageQuue.getInstance();
				while (!Thread.interrupted()) {
					try {
						byte[] obj = msg.getObjMessage();
						for (TextWebSocket member : members) {
							if (!member.isOpen())
								continue;
							try {
								member.sendBinMessage(obj);
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});

	}

	private void parseLitener() {
		try {
			ServletConfig cfg = getServletConfig();
			String listenerCls = cfg.getInitParameter("listener");
			if (listenerCls != null) {
				Object obj = Class.forName(listenerCls).newInstance();
				listener = (MessageListener) obj;
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		ServletContext ctx = getServletContext();
		RequestDispatcher dispatcher = ctx.getNamedDispatcher("default");
		dispatcher.forward(request, response);
	}

	public WebSocket doWebSocketConnect(HttpServletRequest request,
			String protocol) {
		return new TextWebSocket(this);
	}
}
